import React from "react";
import { message, Tabs, Modal } from "antd";
import { connect } from "react-redux";
import { v4 as uuid } from "uuid";
import EditArea from "./components/EditArea";
import SettingTable from "./components/SettingTable";
import WithTooltipProps from "components/WithTooltipBtn";
import EditorLayout from "layout/editorLayout";
import Preview from "./components/Preview";
import { QuestionOutlined, UndoOutlined, RedoOutlined } from "@ant-design/icons"
import { componentTabList, keyPrompt } from "./config";
import { ADD_COMPONENT, ADJUST_COMPONENT_SORT, DELETE_LAYER, REDO_OPERATE, SET_CURRENT_ELEMENT, UNDO_OPERATE } from "store/constants";
import { IEditorProps } from "store/reducers/editor";
import {componentParam} from "utils";
import "./index.scss";

interface IEditorCompProps {
    editor: IEditorProps;
    addComponent: (component: any) => void;
    adjustComponent: (components: any) => void;
    setCurrentElement: (id: string) => void;
    undoOperate: () => void;
    redoOperate: () => void;
    deleteCurrentElement: () => void;
}

interface IEditorState {
    visiblePrompt: boolean;
    visiblePreview: boolean;
}

class Editor extends React.Component<IEditorCompProps, IEditorState> {
    state: IEditorState = {
        visiblePrompt: false,
        visiblePreview: false
    }
    addComponentItem = (props: any, name: string) => {
        const { addComponent, editor } = this.props;
        const maxIndex = editor.components.reduce((prev: number, cur: any) => {
            return cur?.index > prev ? cur?.index : prev;
        }, 0)
        addComponent({
            name,
            id: uuid(),
            index: maxIndex + 1,
            props
        });
    }

    // 删除当前选中元素
    deletCurrentElement = () => {
        const { deleteCurrentElement } = this.props;
        deleteCurrentElement();
        message.success("删除当前图层成功.")
    }

    // 监听键盘键按下
    handleKeyUp = (e: KeyboardEvent) => {
       switch(e.key){
           case "Backspace":
           case "Delete":
                if(!["input", "textarea"].includes((e.target as any).type as string)){
                    this.deletCurrentElement();
                }
                break;
           case "Escape":  // 取消选中
               this.props.setCurrentElement("");
               break;
           default:
               break;
       }
    }

    componentDidMount(){
        document.addEventListener("keyup", this.handleKeyUp, false);
    }
    componentWillUnmount(){
        document.removeEventListener("keyup", this.handleKeyUp, false);
    }

    render(){
        const { editor, undoOperate, redoOperate } = this.props;
        const { visiblePrompt, visiblePreview } = this.state;
        return(<EditorLayout onPreview={() => this.setState({visiblePreview: !visiblePreview})}>
            <div className="editor-wrapper">
                <div className="left-component-wrapper">
                    <Tabs defaultActiveKey={componentTabList.defaultKey}>
                        {
                            componentTabList.tabList.map(item => {
                                const Comp: React.FC<any> = item.component;
                                return <Tabs.TabPane
                                    tab={item.title}
                                    key={item.key}
                                >
                                    <div className="template-list-wrapper">
                                        <ul className="template-list">
                                            {
                                                (item.defaultTemplate as any[]).map((temp, index) => {
                                                    const tempAttr = Object.assign({}, item.defaultValues, temp);
                                                    const { styleProps, componentProps } = componentParam(tempAttr, item.styleKeyNames);
                                                    return <li className="template-item" key={index} onClick={() => this.addComponentItem(tempAttr, item.key)}>
                                                        <Comp {...temp} style={styleProps} componentProps={componentProps} />
                                                    </li>
                                                })
                                            }
                                        </ul>
                                    </div>
                                </Tabs.TabPane>
                            })
                        }
                    </Tabs>
                </div>
                <div className="main-edit-wrapper">
                    <div className="canEdit-main">
                        <EditArea />
                    </div>
                    <div className="tools-btn">
                        <WithTooltipProps
                            message={"快捷键提示"}
                            btnExtra={{
                                onClick: () => this.setState({visiblePrompt: !visiblePrompt})
                            }}
                        ><QuestionOutlined /></WithTooltipProps>
                        <WithTooltipProps
                            message={"撤销"}
                            btnExtra={{
                                disabled: editor.cursor === 0,
                                onClick: () => undoOperate()
                            }}
                        ><UndoOutlined /></WithTooltipProps>
                        <WithTooltipProps
                            message={"重做"}
                            btnExtra={{
                                disabled: editor.cursor === editor.operateList.length,
                                onClick: () => redoOperate()
                            }}
                        ><RedoOutlined /></WithTooltipProps>
                    </div>
                </div>
                <div className="right-props-wrapper">
                    <SettingTable />
                </div>
                <Modal
                    visible={visiblePrompt}
                    title={"快捷键操作"}
                    footer={null}
                    onCancel={() => this.setState({visiblePrompt: !visiblePrompt})}
                    className="key-prompt-modal"
                    width={400}
                >
                    <ul className="key-prompt-wrapper">
                        {
                            keyPrompt.map(keyItem => {
                                return <li className="key-item" key={keyItem.key}>
                                    <span className="key-name">{keyItem.name}</span>
                                    <span className="key-value">{keyItem.key}</span>
                                </li>
                            })
                        }
                    </ul>
                </Modal>
            </div>
            <Preview className="editor-preview" 
                visible={visiblePreview}
                onClose={() => this.setState({visiblePreview: false})}
            />
        </EditorLayout>)
    }
}

export default connect((state: any) => {
    return { editor: state.editor }
}, (dispatch) => {
    return {
        addComponent: (component: any) => dispatch({type: ADD_COMPONENT, payload: component}),
        adjustComponent: (components: any) => dispatch({type: ADJUST_COMPONENT_SORT, payload: components}),
        setCurrentElement: (id: string) => dispatch({ type: SET_CURRENT_ELEMENT, payload: id }),
        undoOperate: () => dispatch({type: UNDO_OPERATE}),
        redoOperate: () => dispatch({type: REDO_OPERATE}),
        deleteCurrentElement: () => dispatch({type: DELETE_LAYER}),
    }
})(Editor);